package com.ccg.service;

import com.ccg.dao.Order_roomDao;
import com.ccg.entity.Message;
import com.ccg.entity.Order;
import com.ccg.entity.Order_Room;
import com.ccg.entity.Room;
import com.ccg.utils.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.ParseException;
import java.util.Date;
import java.util.List;

@Service
public class Order_RoomService {
    @Autowired
    Order_roomDao order_roomDao;
    @Autowired
    Date_Rt_NumberService date_rt_numberService;
    @Autowired
    RoomService roomService;
    @Autowired
    OrderService orderService;

    //用户预定房间时的添加的房间
    //需要订单id，房间类型id，入住时间，退房时间
    public int addOrderRoom(Order_Room order_room) {
        return order_roomDao.addOrderRoom(order_room);
    }

    //前台为该订单房间安排一个房间
    //并将被安排的房间设置为已入住状态
    //成功返回1,失败返回0
    public int addRoomToOrder(Order_Room order_Room) {
        //安排房间
        if (order_roomDao.addRoomToOrder(order_Room) == 1) {
            //安排房间成功,修改被安排的房间的状态为已入住
            Room room = new Room();
            room.setRt_id(order_Room.getRt_id());       //确定房间类型
            room.setRoom_id(order_Room.getRoom_id());   //确定房间编号
            room.setStatus(0);
            if (roomService.updateStatusById(room) == 1) {
                return 1;
            }
        }
        return 0;
    }

    //用户结束某一个房间的使用
    //判断实际退房日期与预计日期的前后关系,并进行相关逻辑处理
    //成功返回1,失败返回0
    public int outRoom(Order_Room order_room) throws ParseException {
        //判断该订单房间是否已被提前结束
        //这种情况是该订单房间之前已被结束,也算成功
        if(order_room.getReal_out_date()!=null && order_room.getReal_out_date()!="")
            return 1;
        //结束一个房间的使用并判断是否成功
        if (order_roomDao.outRoom(order_room.getOr_room_id()) == 1) {
            //结束该房间使用成功,修改被退房的房间的状态为空闲
            Room room = new Room();
            room.setRt_id(order_room.getRt_id());       //确定房间类型
            room.setRoom_id(order_room.getRoom_id());   //确定房间编号
            room.setStatus(1);                  //将被退的房间的状态设为空闲
            if (roomService.updateStatusById(room) != 1) {
                return 0;
            }

            //判断实际退房日期与预计日期的前后关系,并进行相关逻辑处理
            //预计退房日期
            Date out_date = DateUtil.timeFormat(order_room.getOut_date());
            //实际退房日期
            Date real_out_date = DateUtil.dateAddOrMinus(DateUtil.timeFormat(DateUtil.getNowDate()), -1);
            //如果实际退房日期早于预计退房日期,对多预定的房间资源进行释放
            if (real_out_date.before(out_date)) {
                //从退房当天开始到预订的退房日期释放被预定的房间资源
                order_room.setIn_date(DateUtil.getNowDate());
                order_room.setOrder_id(1);
                //如果释放房间资源失败,返回0,否则进一步处理
                if (date_rt_numberService.updateNumberByDateRt_id(order_room) == 0)
                    return 0;
            }
            //所有退房逻辑处理成功
            return 1;
        } else return 0;
    }

    //除了添加事务管理,与上面相同,用于在Controller层单独使用
    @Transactional
    public int outRoom2(Order_Room order_room) throws ParseException {
        //判断该订单房间是否已被提前结束
        //这种情况是该订单房间之前已被结束,也算成功
        if(order_room.getReal_out_date()!=null && order_room.getReal_out_date()!="")
            return 1;
        //结束一个房间的使用并判断是否成功
        if (order_roomDao.outRoom(order_room.getOr_room_id()) == 1) {
            //结束该房间使用成功,修改被退房的房间的状态为空闲
            Room room = new Room();
            room.setRt_id(order_room.getRt_id());       //确定房间类型
            room.setRoom_id(order_room.getRoom_id());   //确定房间编号
            room.setStatus(1);                          //将被退的房间的状态设为空闲
            if (roomService.updateStatusById(room) != 1) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return 0;
            }

            //判断实际退房日期与预计日期的前后关系,并进行相关逻辑处理
            //预计退房日期
            Date out_date = DateUtil.timeFormat(order_room.getOut_date());
            //实际退房日期,与预期退房比较是需-1天
            Date real_out_date = DateUtil.dateAddOrMinus(DateUtil.timeFormat(DateUtil.getNowDate()), -1);
            //如果实际退房日期早于预计退房日期,对多预定的房间资源进行释放
            if (real_out_date.before(out_date)) {
                //从退房当天开始到预订的退房日期释放被预定的房间资源
                order_room.setIn_date(DateUtil.getNowDate());
                order_room.setOrder_id(1);
                //如果释放房间资源失败,返回0,否则进一步处理
                if (date_rt_numberService.updateNumberByDateRt_id(order_room) == 0) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return 0;
                }
            }
            //所有退房逻辑处理成功
            return 1;
        } else return 0;
    }

    //取消删除一个订单房间,只允许删除没有被安排过房间的
    //并判断是否需要对房间资源进行释放
    @Transactional
    public Message deleteOrder_Room(Order_Room order_room) {
        Order order = orderService.findOrderByOrderId(order_room.getOrder_id());
        if (order == null)
            return new Message(1, "该订单不存在", null);
        //删除订单房间
        if (order_roomDao.deleteOrder_Room(order_room.getOr_room_id()) == 1) {
            //该订单未审核
            if (order.getOrderStatus() == 0) {
                order_roomDao.deleteOrder_Room(order_room.getOr_room_id());
                return new Message(0, "操作成功", "取消删除订单房间成功");
            }
            //该订单已被审核,预留了房间,需对房间资源进行释放
            if (order.getOrderStatus() == 1||order.getOrderStatus() == 2) {
                //释放房间资源
                order_room.setOrder_id(1);
                if (date_rt_numberService.updateNumberByDateRt_id(order_room) == 0) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return new Message(1, "操作失败", "未知异常");
                }
                return new Message(0, "操作成功", "取消删除订单房间成功");

            }
            return new Message(1, "操作失败", "该订单状态不允许删除订单房间");
        }
        else return new Message(1, "操作失败", "可能该订单房间已安排房间无法删除");
    }

    //根据订单order_id获取该订单的所有订单房间
    public List<Order_Room> findAllOrderRoom(int order_id) {
        return order_roomDao.findAllOrderRoom(order_id);
    }

}
